/*
 * Copyright 2009 Eat Local Food, LLC
 *
 * This file is part of gwtCommerce.
 *
 * gwtCommerce is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * gwtCommerce is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with gwtCommerce.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.elf.gwt.store.client;

import com.elf.gwt.common.client.CommonComponentController;
import com.elf.gwt.common.client.access.RequestParameter;
import com.elf.gwt.common.client.components.CommonSimpleComponent;
import com.elf.gwt.common.client.model.AbstractModel;
import com.elf.gwt.common.client.model.CartModel;
import com.elf.gwt.common.client.utils.CommonUtils;
import com.elf.gwt.store.client.components.AccountComponent;
import com.elf.gwt.store.client.components.AdvancedSearchComponent;
import com.elf.gwt.store.client.components.AdvancedSearchResultsComponent;
import com.elf.gwt.store.client.components.AlsoPurchasedComponent;
import com.elf.gwt.store.client.components.BestSellersComponent;
import com.elf.gwt.store.client.components.BreadcrumbComponent;
import com.elf.gwt.store.client.components.CartComponent;
import com.elf.gwt.store.client.components.CartSummaryComponent;
import com.elf.gwt.store.client.components.CategoriesComponent;
import com.elf.gwt.store.client.components.CategoriesSummaryComponent;
import com.elf.gwt.store.client.components.CheckoutComponent;
import com.elf.gwt.store.client.components.ContactUsComponent;
import com.elf.gwt.store.client.components.CreateProductReviewComponent;
import com.elf.gwt.store.client.components.CurrenciesComponent;
import com.elf.gwt.store.client.components.FooterComponent;
import com.elf.gwt.store.client.components.HeaderComponent;
import com.elf.gwt.store.client.components.InformationComponent;
import com.elf.gwt.store.client.components.InformationDescriptionComponent;
import com.elf.gwt.store.client.components.LanguagesComponent;
import com.elf.gwt.store.client.components.ManufacturerInfoComponent;
import com.elf.gwt.store.client.components.ManufacturersComponent;
import com.elf.gwt.store.client.components.MultipleResultsComponent;
import com.elf.gwt.store.client.components.NewProductsComponent;
import com.elf.gwt.store.client.components.OrderComponent;
import com.elf.gwt.store.client.components.OrderedProductsComponent;
import com.elf.gwt.store.client.components.OrdersSummaryComponent;
import com.elf.gwt.store.client.components.ProductComponent;
import com.elf.gwt.store.client.components.ProductReviewsComponent;
import com.elf.gwt.store.client.components.ProductXSellComponent;
import com.elf.gwt.store.client.components.RandomReviewComponent;
import com.elf.gwt.store.client.components.SearchComponent;
import com.elf.gwt.store.client.components.SpecialsComponent;
import com.elf.gwt.store.client.components.StoreSimpleComponent;
import com.elf.gwt.store.client.components.TellAFriendComponent;
import com.elf.gwt.store.client.components.TellAFriendEntryComponent;
import com.elf.gwt.store.client.components.UpcomingProductsComponent;
import com.elf.gwt.store.client.components.WhatsNewComponent;
import com.google.gwt.core.client.GWT;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONValue;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.InlineHTML;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.FlexTable.FlexCellFormatter;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class StoreComponentController extends CommonComponentController
{	
	protected GWTCommerceConstants storeConstants;
	protected GWTCommerceModuleConstants storeModuleConstants;
	
	protected boolean informationComponentIsHorizontal = false;
	public boolean thirdPartyPaymentProcess = false;
	protected String storeNameAddress = "";
	protected String homeUrl = "";

	public FlexTable flexTable;
	protected VerticalPanel topPanel;
	protected VerticalPanel leftPanel;
	protected VerticalPanel middlePanel;
	protected VerticalPanel rightPanel;
	protected VerticalPanel bottomPanel;
	
	public static BreadcrumbComponent breadcrumbComponent;
	protected CartSummaryComponent cartSummaryComponent;

	public static AccountComponent accountComponent = null;
	public static CartComponent cartComponent = null;
	public static CategoriesComponent categoriesComponent = null;
	public static CurrenciesComponent currenciesComponent = null;
	public static LanguagesComponent languagesComponent = null;
	public static ManufacturersComponent manufacturersComponent = null;
	public static ProductComponent productComponent = null;
	
	public Panel getDisplayPanel() {
		return flexTable;
	}


	/**
	 * This is the entry point method.
	 */
	public void onModuleLoad()
	{
		storeConstants = GWT.create(GWTCommerceConstants.class);
		storeModuleConstants = GWT.create(GWTCommerceModuleConstants.class);
		multipleResultsComponent = new MultipleResultsComponent(this);

		String[] alwaysAsk = {"BestSellersComponent","WhatsNewComponent","RandomReviewComponent","SpecialsComponent","NewProductsComponent","UpcomingProductsComponent", "OrderedProductsComponent"};
		setAlwaysAskHandles(alwaysAsk);
		
		super.onModuleLoad();
		
		thirdPartyPaymentProcess = false;
	}
	
	protected void processOnModuleLoadBuildDisplayFramework()
	{		
	    flexTable = new FlexTable();
		flexTable.addStyleName("DockPanel");

		topPanel = new VerticalPanel();
		topPanel.addStyleName("TopPanel");

		leftPanel = new VerticalPanel();
		leftPanel.addStyleName("LeftPanel");

		middlePanel = new VerticalPanel();
		middlePanel.addStyleName("MiddlePanel");

		rightPanel = new VerticalPanel();
		rightPanel.addStyleName("RightPanel");

		bottomPanel = new VerticalPanel();
		bottomPanel.addStyleName("BottomPanel");

		FlexCellFormatter cf = flexTable.getFlexCellFormatter();

	    flexTable.setWidget(0, 0, topPanel);
	    cf.setColSpan(0, 0, 3);
	    

	    flexTable.setWidget(1, 0, leftPanel);
	    cf.setVerticalAlignment(1, 0, HasVerticalAlignment.ALIGN_TOP);
	    cf.setWidth(1, 0, "220px");
	    flexTable.setWidget(1, 1, middlePanel);
	    cf.setVerticalAlignment(1, 1, HasVerticalAlignment.ALIGN_TOP);
	    flexTable.setWidget(1, 2, rightPanel);
	    cf.setVerticalAlignment(1, 2, HasVerticalAlignment.ALIGN_TOP);
	    cf.setWidth(1, 2, "220px");

	    flexTable.setWidget(2, 0, bottomPanel);
	    cf.setColSpan(2, 0, 3);
			    
		flexTable.setVisible(false);
	}
	
	protected String processOnModuleLoadParseMetaData(JSONValue jsonInitialValue)
	{
		String token = "";
		JSONValue metaDataValue = CommonUtils.getComponentValue(jsonInitialValue, "GWTCommerceMetaData");

		informationComponentIsHorizontal = false;
		if (metaDataValue != null)
		{
			JSONObject jsonObject;
			if ((jsonObject = metaDataValue.isObject()) != null)
			{
				token = AbstractModel.convertToString(jsonObject,"token");
				boolean testSSL = AbstractModel.convertToBoolean(jsonObject, "testSSL");
				storeNameAddress = AbstractModel.convertToString(jsonObject, "store_name_address");
				homeUrl = AbstractModel.convertToString(jsonObject, "home_url");
				informationComponentIsHorizontal = AbstractModel.convertToBoolean(jsonObject, "information_component_is_horizontal");
				thirdPartyPaymentProcess = AbstractModel.convertToBoolean(jsonObject, "third_party_payment_process");
				if(!GWT.isScript())
				{
					CommonUtils.testSSL = testSSL;
				}
			}
		}
		return token;
	}
	
	protected void processOnModuleLoadParseDataGetComponentPost(CommonSimpleComponent component)
	{
		if (component.getHandle().equals("CurrenciesComponent")) {
			currenciesComponent = (CurrenciesComponent)component;
		}
		else if (component.getHandle().equals("LanguagesComponent")) {
			languagesComponent = (LanguagesComponent)component;
		}
		else if (component.getHandle().equals("ManufacturersComponent")) {
			manufacturersComponent = (ManufacturersComponent)component;
		}
		else if (component.getHandle().equals("AccountComponent")) {
			accountComponent = (AccountComponent)component;
		}
		else if (component.getHandle().equals("CategoriesComponent")) {
			categoriesComponent = (CategoriesComponent)component;
		}
	}

	protected void processOnModuleLoadParseDataPre()
	{
		breadcrumbComponent = (BreadcrumbComponent)getComponent("BreadcrumbComponent");
		cartComponent = (CartComponent)getComponent("CartComponent");
	}
	
	protected void processOnModuleLoadParseDataPost()
	{
		cartSummaryComponent = (CartSummaryComponent)getComponent("CartSummaryComponent");
		
		CommonSimpleComponent headerComponent = getComponent("HeaderComponent");
		headerComponent.build();
		CommonSimpleComponent footerComponent = getComponent("FooterComponent");
		footerComponent.build();
		CommonSimpleComponent searchComponent = getComponent("SearchComponent");
		searchComponent.build();
		cartSummaryComponent.build();

		breadcrumbComponent = (BreadcrumbComponent)getComponent("BreadcrumbComponent");
		if (accountComponent.getAccountModel().getId() > 0) historyToken = "AccountComponent--ViewAccount";
		breadcrumbComponent.setToken(historyToken);
		breadcrumbComponent.build();

		String middleBottomStr = "";
		/*
		for (int i = 0; i< 100; i++)
		{
			middleBottomStr += "&nbsp;";
		}
		*/
		InlineHTML middleBottomHTML = new InlineHTML(middleBottomStr);
		middlePanel.add(middleBottomHTML);

		productComponent = (ProductComponent)getComponent("ProductComponent");
	}
	
	protected void processOnModuleLoadDefaultDisplay()
	{
		getDisplayPanel().setVisible(true);
	}
	
	protected void processUpdateFromHistoryBuildAbort() 
	{
		if (!getDisplayPanel().isVisible()) getDisplayPanel().setVisible(true);
		breadcrumbComponent.setToken(historyToken);
		breadcrumbComponent.build();
	}

	protected void processUpdateFromHistoryBuildPost() 
	{
		cartSummaryComponent.build();
	}

	public void hideComponents()
	{
		int sz = middlePanel.getWidgetCount();
		for (int i = 0; i < sz-1; i++)
		{
			middlePanel.getWidget(i).setVisible(false);
		}
		CommonSimpleComponent component = getComponent("TellAFriendComponent");
		component.setVisible(false);
		component = getComponent("ManufacturerInfoComponent");
		component.setVisible(false);
	}

	public String getComponentTitle(String handle)
	{
		String title = handle;
		if (handle == null)
		{
		}
		else if (handle.equals("AdvancedSearchComponent")) title = storeConstants.AdvancedSearchComponentTitle();
		else if (handle.equals("AdvancedSearchResultsComponent")) title = storeConstants.AdvancedSearchResultsComponentTitle();
		else if (handle.equals("AlsoPurchasedComponent")) title = storeConstants.AlsoPurchasedComponentTitle();
		else if (handle.equals("BestSellersComponent")) title = storeConstants.BestSellersComponentTitle();
		else if (handle.equals("CartComponent")) title = storeConstants.CartComponentTitle();
		else if (handle.equals("CartSummaryComponent")) title = storeConstants.CartSummaryComponentTitle();
		else if (handle.equals("CategoriesComponent")) title = storeConstants.CategoriesComponentTitle();
		else if (handle.equals("CategoriesSummaryComponent")) title = "";
		else if (handle.equals("CheckoutComponent")) title = storeConstants.CheckoutComponentTitle();
		else if (handle.equals("CreateProductReviewComponent")) title = storeConstants.CreateProductReviewComponentTitle();
		else if (handle.equals("CurrenciesComponent")) title = storeConstants.CurrenciesComponentTitle();
		else if (handle.equals("AccountComponent")) title = "";
		else if (handle.equals("InformationComponent")) title = storeConstants.InformationComponentTitle();
		else if (handle.equals("LanguagesComponent")) title = storeConstants.LanguagesComponentTitle();
		else if (handle.equals("NewProductsComponent")) title = storeConstants.NewProductsComponentTitle();
		else if (handle.equals("OrderedProductsComponent")) title = storeConstants.OrderedProductsComponentTitle();
		else if (handle.equals("OrderComponent")) title = storeConstants.OrderComponentTitle();
		else if (handle.equals("OrdersSummaryComponent")) title = storeConstants.OrdersSummaryComponentTitle();
		else if (handle.equals("ManufacturersComponent")) title = storeConstants.ManufacturersComponentTitle();
		else if (handle.equals("ManufacturerInfoComponent")) title = storeConstants.ManufacturerInfoComponentTitle();
		else if (handle.equals("NotificationsComponent")) title = storeConstants.NotificationsComponentTitle();
		else if (handle.equals("ProductComponent")) title = "";
		else if (handle.equals("ProductXSellComponent")) title = storeConstants.ProductXSellComponentTitle();
		else if (handle.equals("ProductReviewsComponent")) title = storeConstants.ProductReviewsComponentTitle();
		else if (handle.equals("RandomReviewComponent")) title = storeConstants.RandomReviewComponentTitle();
		else if (handle.equals("SearchComponent")) title = storeConstants.SearchComponentTitle();
		else if (handle.equals("SpecialsComponent")) title = storeConstants.SpecialsComponentTitle();
		else if (handle.equals("TellAFriendComponent")) title = storeConstants.TellAFriendComponentTitle();
		else if (handle.equals("UpcomingProductsComponent")) title = storeConstants.UpcomingProductsComponentTitle();
		else if (handle.equals("WhatsNewComponent")) title = storeConstants.WhatsNewComponentTitle();
		else if (handle.equals("ContactUsComponent")) title = "Contact Us";

		return title;
	}

	public void removeComponent(String handle)
	{
		CommonSimpleComponent simpleComponent = componentHash.get(handle);
		if (simpleComponent != null) componentHash.remove(simpleComponent);

		int sz = middlePanel.getWidgetCount();
		for (int i = 0; i < sz-1; i++)
		{
			Widget widget = middlePanel.getWidget(i);
			try {
				CommonSimpleComponent sComponent = (StoreSimpleComponent)widget;
				if (sComponent == simpleComponent) {
					middlePanel.remove(widget);
					break;
				}
			}
			catch (Exception e) {}
		}
	}

	public CommonSimpleComponent getComponent(String handle, boolean create)
	{
		if (handle.endsWith("ComponentMetaData")) return null;

		CommonSimpleComponent simpleComponent = componentHash.get(handle);
		Widget component = null;
		if (simpleComponent == null && create)
		{
			if (handle.equals("dummy")) component = null;

			if (handle.equals("AccountComponent")) {
				component = new AccountComponent(this, "Middle");
				middlePanel.insert(component, 0);
			}
			else if (handle.equals("AdvancedSearchComponent")) {
				component = new AdvancedSearchComponent(this, "Middle");
				middlePanel.insert(component, 0);
			}
			else if (handle.equals("AdvancedSearchResultsComponent")) {
				component = new AdvancedSearchResultsComponent(this, "Middle");
				middlePanel.insert(component, 0);
			}
			else if (handle.equals("AlsoPurchasedComponent")) {
				component = new AlsoPurchasedComponent(this, null);
				middlePanel.insert(component, 0);
			}
			else if (handle.equals("BestSellersComponent")) {
				component = new BestSellersComponent(this, null);
				rightPanel.add(component);
			}
			else if (handle.equals("BreadcrumbComponent")) {
				component = new BreadcrumbComponent(this, "Middle");
				topPanel.add(component);
			}
			else if (handle.equals("CartComponent")) {
				component = new CartComponent(this, "Middle");
				middlePanel.insert(component, 0);
			}
			else if (handle.equals("CartSummaryComponent")) {
				component = new CartSummaryComponent(this, null);
				rightPanel.insert(component, 0);
			}
			else if (handle.equals("CategoriesComponent")) {
				component = new CategoriesComponent(this, null);
				leftPanel.add(component);
			}
			else if (handle.equals("CategoriesSummaryComponent")) {
				component = new CategoriesSummaryComponent(this, "Middle");
				middlePanel.insert(component, 0);
			}
			else if (handle.equals("CheckoutComponent")) {
				component = new CheckoutComponent(this, "Middle");
				middlePanel.insert(component, 0);
			}
			else if (handle.equals("CreateProductReviewComponent")) {
				component = new CreateProductReviewComponent(this, "Middle");
				middlePanel.insert(component, 0);
			}
			else if (handle.equals("CurrenciesComponent")) {
				component = new CurrenciesComponent(this, null);
				leftPanel.add(component);
			}
			else if (handle.equals("ContactUsComponent")) {
				component = new ContactUsComponent(this, "Middle");
				middlePanel.insert(component, 0);
			}
			else if (handle.equals("FooterComponent")) {
				component = new FooterComponent(this, "Bottom");
				bottomPanel.add(component);
			}
			else if (handle.equals("HeaderComponent")) {
				component = new HeaderComponent(this, "Middle");
				topPanel.insert(component, 0);
			}
			else if (handle.equals("InformationComponent")) {
				getComponent("BreadcrumbComponent");

				component = new InformationComponent(this, null, informationComponentIsHorizontal);

				if (informationComponentIsHorizontal) 
					topPanel.add(component);
				else
					leftPanel.add(component);
			}
			else if (handle.equals("InformationDescriptionComponent")) {
				component = new InformationDescriptionComponent(this, "Middle");
				middlePanel.insert(component, 0);
			}
			else if (handle.equals("LanguagesComponent")) {
				component = new LanguagesComponent(this, null);
				leftPanel.add(component);
			}
			else if (handle.equals("ManufacturersComponent")) {
				component = new ManufacturersComponent(this, null);
				leftPanel.add(component);
			}
			else if (handle.equals("ManufacturerInfoComponent")) {
				component = new ManufacturerInfoComponent(this, null);
				rightPanel.insert(component, 0);
			}
			else if (handle.equals("NewProductsComponent")) {
				component = new NewProductsComponent(this, null);
				middlePanel.add(component);
			}
			else if (handle.equals("OrderedProductsComponent")) {
				component = new OrderedProductsComponent(this, null);
				rightPanel.add(component);
			}
			else if (handle.equals("OrderComponent")) {
				component = new OrderComponent(this, "Middle");
				middlePanel.insert(component, 0);
			}
			else if (handle.equals("OrdersSummaryComponent")) {
				component = new OrdersSummaryComponent(this, "Middle");
				middlePanel.insert(component, 0);
			}
			else if (handle.equals("ProductComponent")) {
				component = new ProductComponent(this, "Middle");
				middlePanel.insert(component, 0);
			}
			else if (handle.equals("ProductReviewsComponent")) {
				component = new ProductReviewsComponent(this, "Middle");
				middlePanel.insert(component, 0);
			}
			else if (handle.equals("ProductXSellComponent")) {
				component = new ProductXSellComponent(this, null);
				middlePanel.insert(component, 0);
			}
			else if (handle.equals("RandomReviewComponent")) {
				component = new RandomReviewComponent(this, null);
				rightPanel.add(component);
			}
			else if (handle.equals("SearchComponent")) {
				component = new SearchComponent(this, null);
				rightPanel.insert(component, 0);
			}
			else if (handle.equals("SpecialsComponent")) {
				component = new SpecialsComponent(this, null);
				rightPanel.add(component);
			}
			else if (handle.equals("TellAFriendComponent")) {
				component = new TellAFriendComponent(this, null);
				rightPanel.insert(component, 0);
			}
			else if (handle.equals("TellAFriendEntryComponent")) {
				component = new TellAFriendEntryComponent(this, "Middle");
				middlePanel.insert(component, 0);
			}
			else if (handle.equals("UpcomingProductsComponent")) {
				component = new UpcomingProductsComponent(this, null);
				middlePanel.insert(component, 0);
			}
			else if (handle.equals("WhatsNewComponent")) {
				component = new WhatsNewComponent(this, null);
				leftPanel.insert(component, 2);
			}

			if (component != null) {
				simpleComponent = (StoreSimpleComponent)component;
				componentHash.put(handle, simpleComponent);
				component.setVisible(false);
			}
		}
		return simpleComponent;
	}

	public GWTCommerceConstants getStoreConstants() {
		return storeConstants;
	}

	public GWTCommerceModuleConstants getStoreModuleConstants() {
		return storeModuleConstants;
	}

	public String getStoreNameAddress() {
		return storeNameAddress;
	}

	public String getHomeUrl() {
		return homeUrl;
	}

	public void additionalRequestParameters(CommonSimpleComponent component)
	{
		GWT.log("StoreComponentController.additionalRequestParameters start");
		component.addRequestParameter(new RequestParameter("accountId", accountComponent.getAccountModel().getId()));
		component.addRequestParameter(new RequestParameter("categoryId", categoriesComponent.getCategoryModel().getId()));
		component.addRequestParameter(new RequestParameter("languageId", languagesComponent.getLanguageModel().getId()));
		component.addRequestParameter(new RequestParameter("manufacturerId", manufacturersComponent.getManufacturerModel().getId()));
		component.addRequestParameter(new RequestParameter("productId", productComponent.getProductModel().getId()));

		String session = accountComponent.getAccountModel().getSession();
		if (session != null && session.length() > 0)
			component.addRequestParameter(new RequestParameter("accountSession", session));

		CartModel cmodel = cartComponent.getCartModel();
		if (accountComponent.getAccountModel().getId() > 0 && cmodel.isUploadCartRequired())
		{
			component.addRequestParameter(new RequestParameter("cart", cmodel.getCartContents()));
		}
		GWT.log("StoreComponentController.additionalRequestParameters end");
	}
}
